package com.example.chuntiao.cophook.ui;

import android.Manifest;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.design.widget.TabLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.signature.ObjectKey;
import com.example.chuntiao.cophook.R;
import com.example.chuntiao.cophook.adapter.CompPerson;
import com.example.chuntiao.cophook.adapter.PersonAdapter;
import com.example.chuntiao.cophook.beans.Person;
import com.example.chuntiao.cophook.beans.PersonDataSupport;
import com.example.chuntiao.cophook.beans.PersonHideDataSupport;
import com.example.chuntiao.cophook.enums.ResultState;
import com.example.chuntiao.cophook.exception.LogInException;
import com.example.chuntiao.cophook.exception.NewUserException;
import com.example.chuntiao.cophook.mytools.ArrPolisher;
import com.example.chuntiao.cophook.mytools.HttpTool;
import com.example.chuntiao.cophook.mytools.MyApp;
import com.example.chuntiao.cophook.mytools.PhoneTool;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import org.litepal.crud.DataSupport;

import java.io.IOException;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.TimeoutException;

import okio.Timeout;
import permissions.dispatcher.NeedsPermission;
import permissions.dispatcher.OnShowRationale;
import permissions.dispatcher.PermissionRequest;
import permissions.dispatcher.RuntimePermissions;

import static android.app.Activity.RESULT_OK;

/**
 * Created by chuntiao on 17-7-17.
 */

@RuntimePermissions
public class PersionFragment extends Fragment {
    private static final String TAG = "PersionFragment";

    private PersonAdapter mAdapter;
    private MyApp myApp;
    ActionMode actionMode;
    HashSet<View> viewsToHide;
    RecyclerView recyclerView;

    public PersionFragment() {

    }

    public PersonAdapter getmAdapter() {
        return mAdapter;
    }

    public void setmAdapter(PersonAdapter mAdapter) {
        this.mAdapter = mAdapter;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            case MainActivity.REQ_FOR_LOGIN_ACTI:
                if (resultCode == RESULT_OK) {
                    TextView theName = (TextView) ((MainActivity) getActivity()).navigationView.getHeaderView(0).findViewById(R.id.txt_name);
                    TextView theId = (TextView) ((MainActivity) getActivity()).navigationView.getHeaderView(0).findViewById(R.id.txt_uid);

                    String name = data.getStringExtra("uname");
                    String uid = data.getStringExtra("uid");
                    String phone1 = data.getStringExtra("phone1");
                    int imgVer = data.getIntExtra("img_ver", -1);

                    theName.setText(name);
                    theId.setText(uid + "#" + phone1);
                    if (imgVer != -1) {
                        ImageView imgMe = (ImageView) ((MainActivity) getActivity()).navigationView.getHeaderView(0).findViewById(R.id.img_me);
                        Glide.with(getActivity()).load(MyApp.HOST_URL + "image/" + "u_" + uid)
                                .apply(RequestOptions.signatureOf(new ObjectKey(imgVer))).into(imgMe);
                    }

                    ((OrgFragment) ((MainActivity) getActivity()).orgFragment).new LoadDataTask(true).execute();
                    new LoadDataTask(true).execute();//注意　从对话框打开的LogInActivity实际上是从PersonFragment启动的，
                }
                break;
        }
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        myApp = (MyApp) getActivity().getApplication();
        View rootView = inflater.inflate(R.layout.fragment_base, container, false);
        recyclerView = (RecyclerView) rootView.findViewById(R.id.rec_theList);
        LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
        recyclerView.setLayoutManager(layoutManager);
        mAdapter = new PersonAdapter(false, null, null, -1);

        recyclerView.setAdapter(mAdapter);

        return rootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        final Activity activity = getActivity();

        new LoadDataTask().execute();
        mAdapter.setOnClickListener(new PersonAdapter.OnclickListener() {
            @Override
            public void OnNormalBodyLongClick(View v, final int position) {
                viewsToHide = new HashSet<View>();

                v.setBackgroundColor(ContextCompat.getColor(activity, R.color.deep_gray));//长按先选中来源
                viewsToHide.add(v);


                if (actionMode == null) {
                    ((AppCompatActivity) activity).startSupportActionMode(new ActionMode.Callback() {
                        @Override
                        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                            if (actionMode == null) {
                                actionMode = mode;
                                MenuInflater inflater = mode.getMenuInflater();
                                inflater.inflate(R.menu.menu_action_mode, menu);

                                TabLayout tabLayout = (TabLayout) activity.findViewById(R.id.tabs);
                                tabLayout.setVisibility(View.GONE);

                                MyViewPager viewPager = (MyViewPager) activity.findViewById(R.id.viewpager);
                                viewPager.setSwipable(false);


                                MyRefreshLayout refreshLayout = (MyRefreshLayout) activity.findViewById(R.id.swipe_refresh);
                                refreshLayout.setEnabled(false);

                                return true;
                            } else {
                                return false;
                            }
                        }

                        @Override
                        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                            return false;
                        }

                        @Override
                        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                            switch (item.getItemId()) {
                                case R.id.action_hide:
                                    if (viewsToHide.size() == 0)
                                        break;
                                    for (View v : viewsToHide) {

                                        int index = mAdapter.getmPersonList().indexOf(new Person((String) v.getTag(R.id.uid)));
                                        Person p = mAdapter.getmPersonList().get(index);
                                        PersonHideDataSupport peronToHide = new PersonHideDataSupport(p);

                                        peronToHide.save();//数据存储至‘隐藏表’
                                        DataSupport.deleteAll(PersonDataSupport.class, "uid = ? ", p.getUid());//普通表中删除

                                        mAdapter.getmPersonList().remove(p);
                                        mAdapter.notifyItemRemoved((Integer) v.getTag(R.id.position));
                                        v.setBackgroundColor(ContextCompat.getColor(activity, R.color.no_color));//啊我发现当 ｖ 被 mAdapter 移除后并没有销毁，所以可能有颜色残留，太不爽，只好记着把颜色还原
                                    }
                                    mAdapter.notifyItemRangeChanged(0, mAdapter.getmPersonList().size());
                                    viewsToHide.clear();
                                    break;
                                case R.id.action_reset:
                                    for (View v : viewsToHide) {
                                        v.setBackgroundColor(ContextCompat.getColor(activity, R.color.no_color));
                                    }
                                    viewsToHide.clear();
                                    break;
                                case R.id.action_export:
                                    ArrayList<Person> persons = new ArrayList<Person>();
                                    for (View v : viewsToHide) {
                                        int index = mAdapter.getmPersonList().indexOf(new Person((String) v.getTag(R.id.uid)));
                                        Person p = mAdapter.getmPersonList().get(index);
                                        persons.add(p);
                                        v.setBackgroundColor(ContextCompat.getColor(getContext(), R.color.no_color));
                                    }
                                    PersionFragmentPermissionsDispatcher.writeToPhoneWithCheck(PersionFragment.this, (List<Person>) persons.clone());
                                    persons.clear();
                                    viewsToHide.clear();
                                    actionMode.finish();
                                    break;
                            }
                            return true;
                        }

                        @Override
                        public void onDestroyActionMode(ActionMode mode) {

                            TabLayout tabLayout = (TabLayout) activity.findViewById(R.id.tabs);
                            tabLayout.setVisibility(View.VISIBLE);

                            MyViewPager viewPager = (MyViewPager) activity.findViewById(R.id.viewpager);
                            viewPager.setSwipable(true);

                            MyRefreshLayout refreshLayout = (MyRefreshLayout) activity.findViewById(R.id.swipe_refresh);
                            refreshLayout.setEnabled(true);


                            for (View v : viewsToHide) {
                                v.setBackgroundColor(ContextCompat.getColor(activity, R.color.no_color));
                            }
                            viewsToHide.clear();
                            viewsToHide = null;
                            actionMode = null;
                        }
                    });
                }
            }

            @Override
            public void OnNormalBodyClick(View v, int position) {

                if (actionMode == null) {
                    Intent intent = new Intent(getActivity(), PersonDetailActivity.class);
                    intent.putExtra("uname", mAdapter.getmPersonList().get(position).getName());
                    intent.putExtra("phone1", mAdapter.getmPersonList().get(position).getPhone1());
                    intent.putExtra("phone2", mAdapter.getmPersonList().get(position).getPhone2());
                    intent.putExtra("locate", mAdapter.getmPersonList().get(position).getLocate());
                    intent.putExtra("img_ver", mAdapter.getmPersonList().get(position).getImgVer());
                    intent.putExtra("uid", mAdapter.getmPersonList().get(position).getUid());

                    startActivityForResult(intent, MainActivity.REQ_FOR_PERSONDETAIL_ACTI);

                } else {
                    if (viewsToHide.contains(v)) {
                        v.setBackgroundColor(ContextCompat.getColor(activity, R.color.no_color));
                        viewsToHide.remove(v);
                    } else {
                        v.setBackgroundColor(ContextCompat.getColor(activity, R.color.deep_gray));
                        viewsToHide.add(v);
                    }
                }
            }

            @Override
            public void OnNormalPhoneClick(View v, int position) {
                if (actionMode == null)
                    if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CALL_PHONE)
                            != PackageManager.PERMISSION_GRANTED) {
                        ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CALL_PHONE}, PersonDetailActivity.REQ_PERMIT_FOR_CALL);
                    } else {
                        PhoneTool.call(mAdapter.getmPersonList().get(position).getPhone1(), getContext());
                    }
            }
        });
    }


    class LoadDataTask extends AsyncTask<Void, Void, ArrayList<Person>> {


        ResultState state = ResultState.SUCCESS;
        boolean sureFromNet = false;


        LoadDataTask(boolean fromNet) {
            super();
            this.sureFromNet = fromNet;
        }

        LoadDataTask() {
            super();
        }

        void readFromLocal(ArrayList<Person> empList) {
            List<PersonDataSupport> readData = DataSupport.findAll(PersonDataSupport.class);
            for (PersonDataSupport pData : readData)
                empList.add(new Person(pData));

        }

        ResultState readFromNet(ArrayList<Person> empList) {
            String jsonStr = null;
            try {
                jsonStr = HttpTool.sendOkHttpRequest(getActivity(), HttpTool.CODE_PEOPLES, null);
                Gson gson = new Gson();
                ArrayList<Person> newList = gson.fromJson(jsonStr, new TypeToken<ArrayList<Person>>() {
                }.getType());
                for (Person p : newList) {
                    empList.add(p);
                }

                return ResultState.SUCCESS;

            } catch (ConnectException e) {
                e.printStackTrace();
                return ResultState.NO_NET;
            } catch (NewUserException e) {
                return ResultState.NEW_USER;
            } catch (LogInException e) {
                return ResultState.WRONG_PASS;
            }catch (IOException e) {
                e.printStackTrace();
                return ResultState.OTHERS;
            }
        }

        @Override
        protected void onPreExecute() {
            ((MainActivity) getActivity()).swipeRefresh.setRefreshing(true);
        }

        @Override
        protected ArrayList<Person> doInBackground(Void... params) {
            ArrayList<Person> persons = new ArrayList<>();
            if (sureFromNet || myApp.timeToSyn()) {
                state = readFromNet(persons);
                if (state == ResultState.SUCCESS)
                    ArrPolisher.devideCheckRepeatPersonsAndSave(persons);
            } else {
                readFromLocal(persons);//仅从本地读数据，无所谓多余数据，也不用再次存储
            }
            if (state != ResultState.SUCCESS) {
                readFromLocal(persons);//从网络读取失败后，从本地读
            }

            ArrPolisher.polish(persons);
            Collections.sort(persons, new CompPerson());
            {
                Person p = new Person();
                p.setPyOfHomeName("#");
                persons.add(p);
            }

            //myApp.setPersonArrayList(persons);
            return persons;
        }

        @Override
        protected void onPostExecute(ArrayList<Person> persons) {
            if (state == ResultState.SUCCESS) {
                myApp.setLastSync(System.currentTimeMillis());//刷新更新时间
                SharedPreferences.Editor editor = getActivity().getSharedPreferences("data", Context.MODE_PRIVATE).edit();
                editor.putLong("last_sync", myApp.getLastSync());
                editor.apply();
//                mAdapter.setmPersonList(persons);
//
//                mAdapter.notifyDataSetChanged();
            }
            else if (state == ResultState.NO_NET ||state == ResultState.OTHERS)
                new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.sorry)
                        .setMessage("网络错误，请检查网络")
                        .setPositiveButton(R.string.yse, null)
                        .show();

            else if (state == ResultState.NEW_USER)
                new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.welcome)
                        .setMessage("新用户或首次使用，请先登录或注册")
                        .setPositiveButton(R.string.yse, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent intent = new Intent(getActivity(), LogInActivity.class);
                                startActivityForResult(intent, MainActivity.REQ_FOR_LOGIN_ACTI);
                            }
                        })
                        .show();

            else if (state == ResultState.WRONG_PASS)
                new AlertDialog.Builder(getActivity())
                        .setTitle(R.string.sorry)
                        .setMessage("自动登录失败，请手动登录")
                        .setPositiveButton(R.string.yse, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent intent = new Intent(getActivity(), LogInActivity.class);
                                startActivityForResult(intent, MainActivity.REQ_FOR_LOGIN_ACTI);
                            }
                        })
                        .setNegativeButton(R.string.cancel, null)
                        .show();

            ((MainActivity) getActivity()).swipeRefresh.setRefreshing(false);
            mAdapter.setmPersonList(persons);
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PersionFragmentPermissionsDispatcher.onRequestPermissionsResult(this, requestCode, grantResults);
    }

    @NeedsPermission(Manifest.permission.WRITE_CONTACTS)
    void writeToPhone(final List<Person> persons) {

        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                ContentValues values = new ContentValues();
                ContentResolver contentResolver = getActivity().getContentResolver();

                for (Person p : persons) {
                    values.clear();
                    Uri rawContactUri = contentResolver.
                            insert(ContactsContract.RawContacts.CONTENT_URI, values);

                    long rawContactId = ContentUris.parseId(rawContactUri);

                    if (p.getName() != "") {
                        values.clear();
                        values.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
                        values.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE);
                        values.put(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, p.getName());
                        contentResolver.insert(ContactsContract.Data.CONTENT_URI,
                                values);
                    }

                    // 向data表插入电话数据
                    if (p.getPhone1() != "") {
                        values.clear();
                        values.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
                        values.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
                        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, p.getPhone1());
                        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
                        contentResolver.insert(ContactsContract.Data.CONTENT_URI,
                                values);
                    }
                    // 向data表插入电话数据
                    if (p.getPhone2() != "") {
                        values.clear();
                        values.put(ContactsContract.RawContacts.Data.RAW_CONTACT_ID, rawContactId);
                        values.put(ContactsContract.RawContacts.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE);
                        values.put(ContactsContract.CommonDataKinds.Phone.NUMBER, p.getPhone2());
                        values.put(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_HOME);
                        contentResolver.insert(ContactsContract.Data.CONTENT_URI,
                                values);
                    }
                }
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                Snackbar.make(recyclerView, "导出完成", Snackbar.LENGTH_SHORT).show();
            }
        }.execute();
    }

    @OnShowRationale(Manifest.permission.WRITE_CONTACTS)
    void showRationWrite(final PermissionRequest request) {
        new AlertDialog.Builder(getContext())
                .setMessage("需要你授权来写入系统通讯录")
                .setPositiveButton("去授权", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.proceed();
                    }
                })
                .setNegativeButton("朕拒绝", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        request.cancel();
                    }
                })
                .show();
    }

}
